home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DDJ0192.ARJ / HUFFC.C < prev    next >
Text File  |  1991-09-30  |  2KB  |  102 lines

  1. /* ------------------- huffc.c -------------------- */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5.  
  6. #include "htree.h"
  7.  
  8. static void compress(FILE *, int, int);
  9. static void outbit(FILE *fo, int bit);
  10.  
  11. void main(int argc, char *argv[])
  12. {
  13.     FILE *fi, *fo;
  14.     int c;
  15.     BYTECOUNTER bytectr = 0;
  16.     int freqctr = 0;
  17.  
  18.     if (argc < 3)   {
  19.         printf("\nusage: huffc infile outfile");
  20.         exit(1);
  21.     }
  22.  
  23.     if ((fi = fopen(argv[1], "rb")) == NULL)    {
  24.         printf("\nCannot open %s", argv[1]);
  25.         exit(1);
  26.     }
  27.     if ((fo = fopen(argv[2], "wb")) == NULL)    {
  28.         printf("\nCannot open %s", argv[2]);
  29.         fclose(fi);
  30.         exit(1);
  31.     }
  32.  
  33.     ht = calloc(256, sizeof(struct htree));
  34.  
  35.     /* - read the input file and count character frequency - */
  36.     while ((c = fgetc(fi)) != EOF)   {
  37.         c &= 255;
  38.         if (ht[c].cnt == 0)   {
  39.             freqctr++;
  40.             ht[c].ch = c;
  41.         }
  42.         ht[c].cnt++;
  43.         bytectr++;
  44.     }
  45.  
  46.     /* --- write the byte count to the output file --- */
  47.     fwrite(&bytectr, sizeof bytectr, 1, fo);
  48.  
  49.     /* --- write the frequency count to the output file --- */
  50.     fwrite(&freqctr, sizeof freqctr, 1, fo);
  51.  
  52.     /* -- write the frequency array to the output file -- */
  53.     for (c = 0; c < 256; c++)   {
  54.         if (ht[c].cnt > 0)    {
  55.             fwrite(&ht[c].ch, sizeof(char), 1, fo);
  56.             fwrite(&ht[c].cnt, sizeof(BYTECOUNTER), 1, fo);
  57.         }
  58.     }
  59.  
  60.     /* ---- build the huffman tree ---- */
  61.     buildtree();
  62.  
  63.     /* ------ compress the file ------ */
  64.     fseek(fi, 0L, 0);
  65.     while ((c = fgetc(fi)) != EOF)
  66.         compress(fo, (c & 255), 0);
  67.     outbit(fo, -1);
  68.     fclose(fi);
  69.     fclose(fo);
  70. }
  71.  
  72. /* ---- compress a character value into a bit stream ---- */
  73. static void compress(FILE *fo, int h, int child)
  74. {
  75.     if (ht[h].parent != -1)
  76.         compress(fo, ht[h].parent, h);
  77.     if (child)  {
  78.         if (child == ht[h].right)
  79.             outbit(fo, 0);
  80.         else if (child == ht[h].left)
  81.             outbit(fo, 1);
  82.     }
  83. }
  84.  
  85. static char out8;
  86. static int ct8;
  87.  
  88. /* -- collect and write bits to the compressed output file -- */
  89. static void outbit(FILE *fo, int bit)
  90. {
  91.     if (ct8 == 8 || bit == -1)  {
  92.         while (ct8 < 8)    {
  93.             out8 <<= 1;
  94.             ct8++;
  95.         }
  96.         fputc(out8, fo);
  97.         ct8 = 0;
  98.     }
  99.     out8 = (out8 << 1) | bit;
  100.     ct8++;
  101. }
  102.